package cn.enilu.flash.api.controller.h5;

import cn.enilu.flash.api.utils.CodeUtil;
import cn.enilu.flash.bean.entity.task.MoneyInfo;
import cn.enilu.flash.cache.CacheDao;
import cn.enilu.flash.security.JwtUtil;
import cn.enilu.flash.security.ShiroFactroy;
import cn.enilu.flash.service.task.MoneyInfoService;
import cn.enilu.flash.utils.*;
import cn.enilu.flash.bean.entity.system.User;
import cn.enilu.flash.bean.vo.front.Ret;
import cn.enilu.flash.bean.vo.front.Rets;
import cn.enilu.flash.service.system.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@RestController
@RequestMapping("/h5/user")
public class H5UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private CacheDao cacheDao;
    @Autowired
    private MoneyInfoService moneyInfoService;
    @Value("${deptid}")
    private Long deptid;

    /**
     * 用户注册
     * @param userName
     * @param password
     * @param phone
     * @return
     */
    @PostMapping("/register")
    public Ret register(String userName,
                        String password,
                        String phone,
                        String verifyCode){
        if(verifyCode == null || !verify(verifyCode)) return Rets.failure("验证码有误~");
        if(phone == null || !verifyPhone(phone)) return Rets.failure("手机号格式有误~");
        User byAccount = userService.findByAccount(userName);
        if(byAccount!=null){
            return Rets.failure("用户名已存在！");
        }
        User byPhone = userService.findByPhone(phone);
        if(byPhone!=null){
            return Rets.failure("手机号已注册！");
        }
        String salt = RandomUtil.getRandomString(5);
        password = MD5.md5(password, salt);
        User user = new User();
        user.setAccount(userName);
        user.setPassword(password);
        user.setPhone(phone);
        user.setSalt(salt);
        user.setDeptid(deptid);
        user.setAccumulativeIncome(BigDecimal.ZERO);
        user.setBalance(new BigDecimal(100));

        user.setStatus(1);
        user.setAvatar("");// 默认头像
        user = userService.insert(user);
        if(user!=null){
            MoneyInfo moneyInfo = new MoneyInfo();
            moneyInfo.setMoney(user.getBalance());
            moneyInfo.setMoneyExplain("注册赠送100元");
            moneyInfo.setType(9);
            moneyInfo.setBeforeMoney(BigDecimal.ZERO);
            moneyInfo.setAfterMoney(user.getBalance());
            moneyInfo.setCreateBy(user.getId());
            moneyInfoService.insert(moneyInfo);
            return Rets.success();
        }
        return Rets.failure("注册失败！");
    }

    /**
     * 用户登录
     * @param userName
     * @param password
     * @return
     */
    @PostMapping("/login")
    public Ret login(String userName,String password,String verifyCode){
        if(verifyCode == null || !verify(verifyCode.toUpperCase())) return Rets.failure("验证码有误~");
        userName = userName.trim();
        User user = userService.findByAccountForLogin(userName);
        if(user==null){
            return Rets.failure("用户不存在！");
        }
        if(!user.getPassword().equals(MD5.md5(password,user.getSalt()))){
            return Rets.failure("账号或密码错误！");
        }
        if(user.getStatus()==2){
            return Rets.failure("您的账户存在违规行为，已停封账号~");
        }
        String token = userService.loginForToken(user, LoginType.H5);// 登录类型
        ShiroFactroy.me().shiroUser(token, user);
        if(StringUtil.isNotEmpty(token)){
            Map<String,Object> data = new HashMap<>();
            data.put("token",token);
            return Rets.success(data);
        }
        return Rets.failure("登录失败");
    }

    /**
     * 获取验证码
     * @param response
     * @throws IOException
     */
    @GetMapping("/getCode")
    public void getCode(HttpServletResponse response) throws IOException {
        String code = CodeUtil.getCode(response);
        cacheDao.set(CacheDao.VERITYCODE+HttpUtil.getIp(),code,CacheDao.VERITYCODE);// 存验证码
    }

    /**
     * 获取登录用户信息
     * @return
     */
    @GetMapping("/getUserInfo")
    public Ret getUserInfo(){
        User user = userService.get(JwtUtil.getUserId());
        return Rets.success(user);
    }

    /**
     * 修改密码
     * @param oldPassword
     * @param newPassword
     * @return
     */
    @PostMapping("updatePassword")
    public Ret changePassword(String oldPassword,String newPassword, String verifyCode){
        if(verifyCode == null || !verify(verifyCode.toUpperCase())) return Rets.failure("验证码有误~");
        Long userId = JwtUtil.getUserId();
        User user = userService.get(userId);
        if(!user.getPassword().equals(MD5.md5(oldPassword,user.getSalt()))){
            return Rets.failure("旧密码不正确~");
        }
        String salt = RandomUtil.getRandomString(5);
        newPassword = MD5.md5(newPassword, salt);
        user.setSalt(salt);
        user.setPassword(newPassword);
        User update = userService.update(user);
        return update == null? Rets.failure("密码修改失败~"):Rets.success();
    }

    /**
     * 修改手机号及头像
     * @param avatar
     * @param phone
     * @param verifyCode
     * @return
     */
    @PostMapping("updateInfo")
    public Ret updateInfo(@RequestParam(defaultValue = "")String avatar,String phone,String verifyCode){
        if(verifyCode == null || !verify(verifyCode.toUpperCase())) return Rets.failure("验证码有误~");
        if(!verifyPhone(phone)) return Rets.failure("手机号格式有误~");
        User user = userService.get(JwtUtil.getUserId());
        user.setPhone(phone);
        if (StringUtil.isNotNullOrEmpty(avatar)){
            user.setAvatar(avatar);
        }
        User update = userService.update(user);
        return update == null? Rets.failure("修改失败"):Rets.success();
    }

    /**
     * 验证验证码是否正确
     * @param verifyCode
     * @return
     */
    private Boolean verify(String verifyCode){
        String sysVerifyCode = cacheDao.get(CacheDao.VERITYCODE + HttpUtil.getIp(),CacheDao.VERITYCODE); // 系统分配的验证码
        if(StringUtil.isEmpty(verifyCode) || StringUtil.isEmpty(sysVerifyCode) ||
                !verifyCode.toUpperCase().equals(sysVerifyCode)){
            return false;
        }else {
            cacheDao.del(CacheDao.VERITYCODE + HttpUtil.getIp());// 使验证码失效
            return true;
        }
    }

    /**
     * 验证手机号是否正确
     * @param phone
     * @return
     */
    private Boolean verifyPhone(String phone){
        String pattern = "^(13[0-9]|14[5|7]|15[0|1|2|3|4|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8}$";
        Pattern r = Pattern.compile(pattern);
        Matcher matcher = r.matcher(phone);
        return matcher.matches();
    }
}
